package net.blank.movie
{
	import flash.display.BitmapData;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.utils.getTimer;
	
	import net.blank.bitmapOperation.BitmapDraw;
	import net.blank.timerUtl.PublicTimer;
	
	/**开始播放*/
	[Event(name="start", type="MovieEvent")]
	
	/**开始播放*/
	[Event(name="stop", type="MovieEvent")]
	
	/**当前帧序列播放完成(当 repeatCount 属性值为 1 时,同 STOP 事件同时触发)*/
	[Event(name="frames_end", type="MovieEvent")]
	
	/**
	 * 基于 PublicTimer 的动画类
	 * @author blank
	 * 
	 */
	public class MovieForTimer extends Sprite
	{
		/**
		 * 计时器(执行间隔500ms)
		 */
		protected static const TIMER_25MS:PublicTimer=new PublicTimer(25);
		
		/**帧源图像*/
		protected var _frameSource:BitmapData;
		
		/**帧集合*/
		protected var _frames:Vector.<Frame>;
		
		/**绘制帧的时间间隔(毫秒)*/
		public var frameDrawInterval:uint=40;
		
		/**是否正在播放*/
		protected var _isRunning:Boolean;
		
		/**下一帧编号*/
		protected var $nextFrameId:uint;
		
		/**当前应该绘制的帧*/
		protected var $curDrawFrame:Frame;
		
		/**是否需要绘制*/
		protected var $isNeedDraw:Boolean;
		
		/**上一帧绘制的时间*/
		protected var $lastFrameDrawTime:int;
		
		/**
		 * 重复播放次数(如果此值设置的比较大,在不使用时一定要调用 stop() 方法停止播放.)
		 */
		public var repeatCount:uint;
		
		/**
		 * 绘制帧
		 * 
		 */
		protected function $drawFrame():void{
			graphics.clear();
			
			BitmapDraw.drawBitmap(
				graphics,
				_frameSource,
				$curDrawFrame.drawRect,
				$curDrawFrame.srcRect
			);
			$isNeedDraw=false;
		}
		
		/**
		 * 图像渲染
		 * @param evt
		 * 
		 */
		protected function renderHandler(evt:Event):void{
			if($isNeedDraw){
				$drawFrame();
			}
		}
		
		/**
		 * 计时器事件
		 * @return 
		 * 
		 */
		protected function timeHandler():Boolean{
			var curTime:int=getTimer();
			if((curTime - $lastFrameDrawTime) >= frameDrawInterval){
				var nextframe:Frame=_frames[$nextFrameId];
				if($curDrawFrame != nextframe){
					$curDrawFrame=nextframe;
					
					if(stage && visible){
						$isNeedDraw=true;
						stage.invalidate();
					}
				}
				
				$nextFrameId++;
				if($nextFrameId == _frames.length){
					$nextFrameId=0;
					if(repeatCount == 0){
						stop();
					}else{
						repeatCount--;
					}
					
					dispatchEvent(new MovieEvent(MovieEvent.FRAMES_END));
				}
				
				$lastFrameDrawTime=curTime;
			}
			return false;
		}
		
		/**
		 * 初添加进舞台
		 * @param evt
		 * 
		 */
		protected function addToStageHandler(evt:Event):void{
			if(visible && _isRunning){
				stage.addEventListener(Event.RENDER,renderHandler);
			}
		}
		
		/**
		 * 从舞台移除
		 * @param evt
		 * 
		 */
		protected function removeFromStageHandler(evt:Event):void{
			if(_isRunning && visible){
				stage.removeEventListener(Event.RENDER,renderHandler);
			}
		}
		
		/**
		 * 停止
		 * 
		 */
		public function stop():void{
			if(_isRunning){
				if(stage && visible){
					stage.removeEventListener(Event.RENDER,renderHandler);
				}
				
				TIMER_25MS.removeFunc(timeHandler);
				_isRunning=false;
				
				dispatchEvent(new MovieEvent(MovieEvent.STOP));
			}
		}
		
		/**
		 * 播放
		 * 
		 */
		public function play():void{
			if(_frameSource && _frames && _frames.length > 0){
				if(!_isRunning){
					if(stage && visible){
						stage.addEventListener(Event.RENDER,renderHandler);
					}
					
					TIMER_25MS.addFunc(timeHandler);
					_isRunning=true;
					
					dispatchEvent(new MovieEvent(MovieEvent.START));
				}
			}
		}
		
		/**
		 * 跳转的指定的帧,并停止播放
		 * @param frameId
		 * 
		 */
		public function gotoAndStop(frameId:uint):void{
			stop();
			if(_frameSource && frameId < _frames.length){
				$curDrawFrame=_frames[frameId];
				$drawFrame();
			}
		}
		
		/**
		 * 从指定的帧开始播放
		 * @param frameId
		 * 
		 */
		public function gotoAndPlay(frameId:uint):void{
			if(_frameSource && frameId < _frames.length){
				$curDrawFrame=_frames[frameId];
				play();
			}
		}
		
		/**
		 * 摧毁
		 * @return 
		 * 
		 */
		public function destory():void{
			stop();
			
			removeEventListener(Event.ADDED_TO_STAGE,addToStageHandler);
			removeEventListener(Event.REMOVED_FROM_STAGE,removeFromStageHandler);
		}
		
		/**
		 * 基于 PublicTimer 的动画类(在不使用时,一定要调用 stop() 方法停止播放)
		 * @param frameSource
		 * @param frames
		 * 
		 */
		public function MovieForTimer(
			frameSource:BitmapData=null,
			frames:Vector.<Frame>=null
		){
			_frameSource=frameSource;
			_frames=frames;
			
			gotoAndStop(0);
			
			addEventListener(Event.ADDED_TO_STAGE,addToStageHandler);
			addEventListener(Event.REMOVED_FROM_STAGE,removeFromStageHandler);
		}
		
		override public function set visible(value:Boolean):void{
			if(value != super.visible){
				super.visible=value;
				if(stage && _isRunning){
					if(super.visible){
						stage.addEventListener(Event.RENDER,renderHandler);
					}else{
						stage.removeEventListener(Event.RENDER,renderHandler);
					}
				}
			}
		}
		
		/**帧源图像*/
		public function set frameSource(value:BitmapData):void{
			if(value != _frameSource){
				_frameSource=value;
				
				$drawFrame();
			}
		}
		public function get frameSource():BitmapData{
			return _frameSource;
		}
		
		/**帧集合*/
		public function set frames(value:Vector.<Frame>):void{
			if(value != _frames){
				_frames=value;
				
				gotoAndStop(0);
			}
		}
		public function get frames():Vector.<Frame>{
			return _frames;
		}
		
		/**是否正在播放*/
		public function get isRunning():Boolean{
			return _isRunning;
		}
	}
}